package com.ht.WeNas.utils;

import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;

import java.nio.file.Path;
import java.util.*;

public class FileNameGrouper {
    public static int equalLens(String s1, String s2) {
        if (StrUtil.isBlank(s1) || StrUtil.isBlank(s2)) {
            return 0;
        }
        int len = Math.min(s1.length(), s2.length());
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        for (int i = 0; i < len; i++) {
            if (c1[i] == c2[i]) {
                continue;
            }
            return i;
        }
        return len;
    }

    /**
     * 将文件按照文件夹分类
     * @param paths 需要分类的文件
     * @return 分类结果
     */
    public static Pair<List<Path>, List<List<Path>>> groupFilesByFolder(List<Path> paths) {
        Map<Path, List<Path>> map = new HashMap<>();
        paths.forEach(item -> {
            Path parent = item.getParent();
            if (map.containsKey(parent)) {
                List<Path> list = map.get(parent);
                list.add(item);
            } else {
                List<Path> list = new ArrayList<>();
                list.add(item);
                map.put(parent, list);
            }
        });
        return new Pair<>(map.keySet().stream().toList(), map.values().stream().toList());
    }
    
    /**
     * 传入已经排序的Path，根据相邻文件名前缀相似度进行分组
     * 
     * @param list 已经排序的Path
     * @param minBreakSize 最小打断长度，如果两个路径前缀不同的字符串长度超过了这个数字，就会被分到两个不同的数组中
     * @return 分类完成的数组
     */
    public static List<List<Path>> groupFilesBySimilarity(List<Path> list, int minBreakSize) {
        List<List<Path>> res = new ArrayList<>();
        if (list == null || list.isEmpty()) {
            return res;
        }
        int len = list.size();
        if (len < 5) {
            res.add(list.stream().toList());
            return res;
        }
        List<Path> l = new ArrayList<>();
        l.add(list.get(0));
        res.add(l);
        for (int i = 1; i < len - 1; i++) {
            String s0 = list.get(i - 1).toString();
            String s1 = list.get(i).toString();
            String s2 = list.get(i + 1).toString();
            if (equalLens(s0, s1) - equalLens(s1, s2) < minBreakSize) {
                l.add(list.get(i));
            } else {
                l.add(list.get(i));
                l = new ArrayList<>();
                res.add(l);
            }
        }
        l.add(list.get(len - 1));
        return res;
    }
}
